/*!
 * \file frexp_comm.h
 *
 * \brief 关联连接共通管理
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 * 关联连接共通管理
 *
 * \version 2.0
 * \author yaohl
 * \date 2015/07/27
 *
 */

#ifndef __FREXP_COMM_H_
#define __FREXP_COMM_H_

#include <sys/time.h>
#include "frlist.h"

/*!
* @brief 关联链路分析用\n
* 例如，Oracle收到Redirect包后，根据包体内容获得重定向端口后，创建conntrack_expecting
*/
typedef struct __st_exp
{
    u_short us_proto;   /*!< 6(IPPROTO_TCP) / 17(IPPROTO_UDP) */
    u_int   ui_src_ip;      /*!< 客户端ip 没有设置0*/
    u_short us_src_port;    /*!< 客户端port 没有设置0*/
    u_int   ui_dst_ip;      /*!< 希望连接服务器的ip */
    u_short us_dst_port;    /*!< 希望连接服务器的port */

    u_int   master_src_ip;     /*!< 原始:客户端ip */
    u_short master_src_port;   /*!< 原始:客户端port */
    u_int   master_dst_ip;     /*!< 原始:服务器的ip */
    u_short master_dst_port;   /*!< 原始:服务器的port */
    L7_module *p_master_l7_module;  /*!< 原始:ct上的协议分析 */

    //u_int   stat_src_ip;        /* 统计用:客户端ip */
    u_short stat_src_port;      /*!< 统计用:客户端port 没有设置0 */
    //u_int   stat_dst_ip;        /*!< 统计用:服务器的ip */
    u_short stat_dst_port;      /*!< 统计用:服务器的port 没有设置0 */
    int i_l7_proto;             /*!< 强制设定:ct上的协议分析 */

    Frlist_header *p_lst_hdr_param;   /*!< 参数列表 内部使用 Frvar_field */
    struct timeval st_timeval_upd;
} Frexp;

/*!
 * 关联连接用哈希key
 *
 * \param us_proto     (协议 tcp/udp)
 * \param ui_src_ip    (原地址)
 * \param us_src_port  (原port)
 * \param ui_dst_ip    (目的地址)
 * \param us_dst_port  (目的port)
 * \param p_key        (保存地址)
 * \param ui_key_size  (保存地址长度)
 *
 * \return key长度(出错是为0)
 *
 */
int frexpect_hash_key(u_short us_proto
                    , u_int ui_src_ip
                    , u_short us_src_port
                    , u_int ui_dst_ip
                    , u_short us_dst_port
                    , char *p_key
                    , unsigned int ui_key_size);

/*!
 * 增加关联连接
 *
 * \param p_frame_ref  (框架引用信息)
 * \param us_proto     (协议 tcp/udp)
 * \param ui_dst_ip    (重定向后服务器ip)
 * \param us_dst_port  (重定向后服务器port)
 * \param p_st_ct      (Conntrack *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frexpect_add(void* p_frame_ref ,u_short us_proto, u_int ui_dst_ip, u_short us_dst_port, Conntrack *p_st_ct);

/*!
 * 增加关联连接
 *
 * \param p_frame_ref  (框架引用信息)
 * \param us_proto     (协议 tcp/udp)
 * \param ui_src_ip    (重定向后原ip)
 * \param us_src_port  (重定向后原port)
 * \param ui_dst_ip    (重定向后服务器ip)
 * \param us_dst_port  (重定向后服务器port)
 * \param us_stat_src_port (统计用:客户端port)
 * \param us_stat_dst_port (统计用:服务器的port)
 * \param p_lst_hdr        (存放Frvar_field的链表)
 * \param p_st_ct      (Conntrack *)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frexpect_add2(void* p_frame_ref
               , u_short us_proto
               , u_int ui_src_ip
               , u_short us_src_port
               , u_int ui_dst_ip
               , u_short us_dst_port
               , u_short us_stat_src_port
               , u_short us_stat_dst_port
               , int i_l7_proto
               , Frlist_header *p_lst_hdr
               , Conntrack *p_st_ct);

/*!
 * 获取关联连接上的ct
 *
 * \param p_st_ct      (Conntrack *)
 *
 * \return Frlist_header*
 *
 * \note 注意：获取到后,原来参数设置为NULL(该链表需要在获取的协议模块中释放)
 *
 */
Frlist_header *frexpect_get_param(Conntrack *p_st_ct);

/*!
 * 获取进行关联的的ip信息
 *
 * \param p_st_ct          (Conntrack *)
 * \param p_ui_src_ip      (进行关联时使用的原ip, 可以为NULL)
 * \param p_us_src_port    (进行关联时使用的原port, 可以为NULL)
 * \param p_ui_dst_ip      (进行关联时使用的目的ip, 可以为NULL)
 * \param p_us_dst_port    (进行关联时使用的目的port, 可以为NULL)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frexpect_get_exp_ip(Conntrack *p_st_ct, u_int *p_ui_src_ip, u_short *p_us_src_port, u_int *p_ui_dst_ip, u_short *p_us_dst_port);

/*!
 * 释放关联连接上参数列表
 *
 * \param pp_list_hdr      (Frlist_header **)
 *
 */
void frexpect_free_param(Frlist_header **pp_list_hdr);

#endif
